package drds.plus.datasource.api;


import drds.plus.common.lifecycle.AbstractLifecycle;
import drds.plus.datasource.configuration.DatabaseStatus;
import drds.plus.datasource.configuration.DatabaseStatusListener;
import drds.plus.datasource.configuration.DatasourceHandler;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 动态数据源，支持数据源参数动态修改
 */
@Slf4j
public class DataSource extends AbstractLifecycle {

    private static Map<String, DatasourceHandler> datasourceIdToDatasourceConfigurationfHandlerMap = new HashMap<String, DatasourceHandler>();

    private volatile DatasourceHandler datasourceHandler = new DatasourceHandler();

    /**
     * 清除掉所有数据源
     */
    public static void cleanAllDataSource() {
        synchronized (datasourceIdToDatasourceConfigurationfHandlerMap) {
            for (DatasourceHandler datasourceHandler : datasourceIdToDatasourceConfigurationfHandlerMap.values()) {
                try {
                    datasourceHandler.destroyDataSource();
                } catch (Exception e) {
                    log.info("destory DatasourceHandler failed!", e);
                    continue;
                }
            }
            datasourceIdToDatasourceConfigurationfHandlerMap.clear();
        }
    }

    public void init(String applicationId, String datasourceId) {
        setApplicationId(applicationId);
        setDatasourceId(datasourceId);

        init();
    }

    public void doInit() {

        String datasourceId = this.getDatasourceId();
        synchronized (datasourceIdToDatasourceConfigurationfHandlerMap) {
            DatasourceHandler datasourceHandler = datasourceIdToDatasourceConfigurationfHandlerMap.get(datasourceId);
            if (null == datasourceHandler) {
                // 初始化config的管理器
                this.datasourceHandler.init();
                datasourceIdToDatasourceConfigurationfHandlerMap.put(datasourceId, this.datasourceHandler);
                log.info("create new DatasourceHandler databaseName : " + datasourceId);
            } else {
                this.datasourceHandler = datasourceHandler;
                log.info("use the cache DatasourceHandler databaseName : " + datasourceId);
            }
        }
    }

    protected void doDestroy() {
        String datasourceId = this.getDatasourceId();
        synchronized (datasourceIdToDatasourceConfigurationfHandlerMap) {
            this.datasourceHandler.destroyDataSource();
            datasourceIdToDatasourceConfigurationfHandlerMap.remove(datasourceId);
        }
    }

    /**
     * 销毁数据源，慎用
     */

    public void destroyDataSource() throws Exception {
        destroy();
    }

    public String getApplicationId() {
        return this.datasourceHandler.getApplicationId();
    }

    public void setApplicationId(String applicationId) {
        this.datasourceHandler.setApplicationId(applicationId);
    }

    public String getDatasourceId() {
        return this.datasourceHandler.getDatasourceId();
    }

    public void setDatasourceId(String datasourceId) {
        this.datasourceHandler.setDatasourceId(datasourceId);
    }

    public DatabaseStatus getDatabaseStatus() {
        return this.datasourceHandler.getDatabaseStatus();
    }

    public void setDatabaseStatusListenerList(List<DatabaseStatusListener> dbStatusListeners) {
        this.datasourceHandler.setDatabaseStatusListenerList(dbStatusListeners);
    }

    public void setSingleInGroup(boolean isSingleInGroup) {
        this.datasourceHandler.setSingleInGroup(isSingleInGroup);
    }

    public void setConnectionProperties(Map<String, String> map) {

    }

    public DataSourceWrapper getDataSourceWrapper() throws SQLException {
        return this.datasourceHandler.getDataSourceWrapper();
    }

    @Override
    public Logger log() {
        return log;
    }
}
